package club.mrxiao.gps.task;

import club.mrxiao.baidu.api.BaiduTraceService;
import club.mrxiao.baidu.domain.BaiduTraceTrackPoint;
import club.mrxiao.baidu.response.BaiduTraceTrackAddPointsResponse;
import club.mrxiao.gps.common.constant.GpsCacheKeyConstant;
import club.mrxiao.gps.service.RedisService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * 轨迹上传任务
 * @author xiaoyu
 */
@Slf4j
@Component
public class PointUploadTask {

    private final RedisService redisService;
    private final BaiduTraceService baiduTraceService;

    @Autowired
    public PointUploadTask(RedisService redisService, BaiduTraceService baiduTraceService) {
        this.redisService = redisService;
        this.baiduTraceService = baiduTraceService;
    }

    @Scheduled(fixedDelayString = "${gps.upload-frequency}")
    public void run() {
        try {
            log.info("读取轨迹点数据");
            Set<String> list = this.redisService.zrange(GpsCacheKeyConstant.GPS_DATA_LIST,0,100);
            List<BaiduTraceTrackPoint> points = new ArrayList<>();
            for (String pointStr : list){
                JSONObject json = JSONObject.parseObject(pointStr);
                BaiduTraceTrackPoint point = JSON.toJavaObject(json,BaiduTraceTrackPoint.class);
                points.add(point);
                redisService.zrem(GpsCacheKeyConstant.GPS_DATA_LIST,pointStr);
            }
            if(points.size() > 0){
                log.info("轨迹上传开始");
                BaiduTraceTrackAddPointsResponse response = baiduTraceService.getTrackService().trackAddPoints(points);
                log.info("轨迹上传结束,上传点数：{},成功点数：{}",points.size(),response.getSuccessNum());
                List<BaiduTraceTrackPoint> paramErrors = response.getFailInfo().getParamError();
                try {
                    if(paramErrors.size() > 0){
                        log.info("由于参数错误,未上传点数：{}",paramErrors.size());
                        for(BaiduTraceTrackPoint point : paramErrors){
                            String pointStr = JSON.toJSONString(point);
                            this.redisService.zadd(GpsCacheKeyConstant.PARAM_ERROR_LIST,Double.valueOf(point.getLocTime()),pointStr);
                        }
                    }
                    List<BaiduTraceTrackPoint> internalErrors = response.getFailInfo().getInternalError();
                    if(internalErrors.size() > 0){
                        log.info("由于接收服务器错误,未上传点数：{}",internalErrors.size());
                        for(BaiduTraceTrackPoint point : internalErrors){
                            String pointStr = JSON.toJSONString(point);
                            this.redisService.zadd(GpsCacheKeyConstant.INTERNAL_ERROR_LIST,Double.valueOf(point.getLocTime()),pointStr);
                        }
                    }
                } catch (Exception e) {
                    log.error("未上传成功轨迹点保存失败",e);
                }
            }else{
                log.info("无轨迹点数据");
            }
        } catch (Exception e) {
            log.error("轨迹上传任务执行失败",e);
        }
    }
}
